#include "dtu_modbus.h"
#include "dtu_log.h"
#include "dtu_memory.h"
#include <termios.h>
#include <fcntl.h>
#include <sys/select.h>

/* CRC16表 */
static const uint16_t crc16_table[256] = {
    0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
    0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
    0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
    0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
    0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
    0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
    0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
    0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
    0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
    0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
    0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
    0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
    0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
    0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
    0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
    0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
    0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
    0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
    0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
    0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
    0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
    0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
    0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
    0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
    0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
    0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
    0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
    0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
    0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
    0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
    0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
    0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};

/* 内部函数声明 */
static dtu_error_t configure_serial_port(int fd, const serial_config_t* config);
static dtu_error_t send_frame(modbus_context_t* ctx, const modbus_frame_t* frame);
static dtu_error_t receive_frame(modbus_context_t* ctx, modbus_frame_t* frame);
static dtu_error_t wait_for_response(modbus_context_t* ctx, int timeout_ms);

modbus_context_t* dtu_modbus_init(modbus_mode_t mode, const serial_config_t* serial_config)
{
    if (!serial_config) {
        return NULL;
    }

    modbus_context_t* ctx = DTU_MALLOC(sizeof(modbus_context_t));
    if (!ctx) {
        return NULL;
    }

    memset(ctx, 0, sizeof(modbus_context_t));
    ctx->mode = mode;
    ctx->serial_config = *serial_config;
    ctx->serial_fd = -1;
    ctx->default_slave_id = 1;
    ctx->response_timeout = 1000; /* 1秒默认超时 */
    ctx->frame_timeout = 100;     /* 100ms帧间超时 */

    /* 初始化互斥锁 */
    if (pthread_mutex_init(&ctx->mutex, NULL) != 0) {
        DTU_FREE(ctx);
        return NULL;
    }

    ctx->initialized = true;

    DTU_LOG_INFO("Modbus context initialized in %s mode", 
                 mode == MODBUS_MODE_RTU ? "RTU" : "ASCII");
    return ctx;
}

void dtu_modbus_cleanup(modbus_context_t* ctx)
{
    if (!ctx) {
        return;
    }

    /* 断开连接 */
    dtu_modbus_disconnect(ctx);

    /* 销毁互斥锁 */
    if (ctx->initialized) {
        pthread_mutex_destroy(&ctx->mutex);
    }

    DTU_FREE(ctx);
    DTU_LOG_INFO("Modbus context cleanup completed");
}

dtu_error_t dtu_modbus_connect(modbus_context_t* ctx)
{
    if (!ctx || !ctx->initialized) {
        return DTU_ERROR_INVALID_PARAM;
    }

    pthread_mutex_lock(&ctx->mutex);

    /* 如果已经连接，直接返回 */
    if (ctx->serial_fd >= 0) {
        pthread_mutex_unlock(&ctx->mutex);
        return DTU_OK;
    }

    /* 打开串口设备 */
    ctx->serial_fd = open(ctx->serial_config.device, O_RDWR | O_NOCTTY | O_NDELAY);
    if (ctx->serial_fd < 0) {
        pthread_mutex_unlock(&ctx->mutex);
        DTU_LOG_ERROR("Failed to open serial device: %s", ctx->serial_config.device);
        return DTU_ERROR_NETWORK;
    }

    /* 配置串口参数 */
    if (configure_serial_port(ctx->serial_fd, &ctx->serial_config) != DTU_OK) {
        close(ctx->serial_fd);
        ctx->serial_fd = -1;
        pthread_mutex_unlock(&ctx->mutex);
        DTU_LOG_ERROR("Failed to configure serial port");
        return DTU_ERROR_NETWORK;
    }

    pthread_mutex_unlock(&ctx->mutex);

    DTU_LOG_INFO("Modbus connected to %s", ctx->serial_config.device);
    return DTU_OK;
}

void dtu_modbus_disconnect(modbus_context_t* ctx)
{
    if (!ctx || !ctx->initialized) {
        return;
    }

    pthread_mutex_lock(&ctx->mutex);

    if (ctx->serial_fd >= 0) {
        close(ctx->serial_fd);
        ctx->serial_fd = -1;
        DTU_LOG_INFO("Modbus disconnected");
    }

    pthread_mutex_unlock(&ctx->mutex);
}

dtu_error_t dtu_modbus_set_slave_id(modbus_context_t* ctx, uint8_t slave_id)
{
    if (!ctx || !ctx->initialized) {
        return DTU_ERROR_INVALID_PARAM;
    }

    pthread_mutex_lock(&ctx->mutex);
    ctx->default_slave_id = slave_id;
    pthread_mutex_unlock(&ctx->mutex);

    return DTU_OK;
}

dtu_error_t dtu_modbus_set_response_timeout(modbus_context_t* ctx, int timeout)
{
    if (!ctx || !ctx->initialized || timeout <= 0) {
        return DTU_ERROR_INVALID_PARAM;
    }

    pthread_mutex_lock(&ctx->mutex);
    ctx->response_timeout = timeout;
    pthread_mutex_unlock(&ctx->mutex);

    return DTU_OK;
}

dtu_error_t dtu_modbus_read_holding_registers(modbus_context_t* ctx, uint8_t slave_id,
                                              uint16_t start_address, uint16_t quantity, uint16_t* registers)
{
    if (!ctx || !ctx->initialized || !registers || quantity == 0 || quantity > 125) {
        return DTU_ERROR_INVALID_PARAM;
    }

    /* 构建请求 */
    modbus_request_t request;
    request.slave_id = slave_id;
    request.function_code = MODBUS_FC_READ_HOLDING_REGISTERS;
    request.start_address = start_address;
    request.quantity = quantity;
    request.data = NULL;
    request.data_length = 0;

    /* 发送请求并接收响应 */
    modbus_response_t response;
    dtu_error_t ret = dtu_modbus_send_request(ctx, &request, &response);
    if (ret != DTU_OK) {
        return ret;
    }

    /* 检查响应 */
    if (response.exception != MODBUS_EXCEPTION_NONE) {
        DTU_LOG_ERROR("Modbus exception: %s", dtu_modbus_exception_string(response.exception));
        dtu_modbus_free_response(&response);
        return DTU_ERROR;
    }

    if (response.byte_count != quantity * 2) {
        DTU_LOG_ERROR("Invalid response byte count: expected %d, got %d", quantity * 2, response.byte_count);
        dtu_modbus_free_response(&response);
        return DTU_ERROR;
    }

    /* 提取寄存器值 */
    for (uint16_t i = 0; i < quantity; i++) {
        registers[i] = (response.data[i * 2] << 8) | response.data[i * 2 + 1];
    }

    dtu_modbus_free_response(&response);
    return DTU_OK;
}

dtu_error_t dtu_modbus_read_input_registers(modbus_context_t* ctx, uint8_t slave_id,
                                           uint16_t start_address, uint16_t quantity, uint16_t* registers)
{
    if (!ctx || !ctx->initialized || !registers || quantity == 0 || quantity > 125) {
        return DTU_ERROR_INVALID_PARAM;
    }

    /* 构建请求 */
    modbus_request_t request;
    request.slave_id = slave_id;
    request.function_code = MODBUS_FC_READ_INPUT_REGISTERS;
    request.start_address = start_address;
    request.quantity = quantity;
    request.data = NULL;
    request.data_length = 0;

    /* 发送请求并接收响应 */
    modbus_response_t response;
    dtu_error_t ret = dtu_modbus_send_request(ctx, &request, &response);
    if (ret != DTU_OK) {
        return ret;
    }

    /* 检查响应 */
    if (response.exception != MODBUS_EXCEPTION_NONE) {
        DTU_LOG_ERROR("Modbus exception: %s", dtu_modbus_exception_string(response.exception));
        dtu_modbus_free_response(&response);
        return DTU_ERROR;
    }

    if (response.byte_count != quantity * 2) {
        DTU_LOG_ERROR("Invalid response byte count: expected %d, got %d", quantity * 2, response.byte_count);
        dtu_modbus_free_response(&response);
        return DTU_ERROR;
    }

    /* 提取寄存器值 */
    for (uint16_t i = 0; i < quantity; i++) {
        registers[i] = (response.data[i * 2] << 8) | response.data[i * 2 + 1];
    }

    dtu_modbus_free_response(&response);
    return DTU_OK;
}

dtu_error_t dtu_modbus_write_single_register(modbus_context_t* ctx, uint8_t slave_id,
                                             uint16_t address, uint16_t value)
{
    if (!ctx || !ctx->initialized) {
        return DTU_ERROR_INVALID_PARAM;
    }

    /* 构建请求 */
    modbus_request_t request;
    request.slave_id = slave_id;
    request.function_code = MODBUS_FC_WRITE_SINGLE_REGISTER;
    request.start_address = address;
    request.quantity = 1;
    
    uint8_t data[2];
    data[0] = (value >> 8) & 0xFF;
    data[1] = value & 0xFF;
    request.data = data;
    request.data_length = 2;

    /* 发送请求并接收响应 */
    modbus_response_t response;
    dtu_error_t ret = dtu_modbus_send_request(ctx, &request, &response);
    if (ret != DTU_OK) {
        return ret;
    }

    /* 检查响应 */
    if (response.exception != MODBUS_EXCEPTION_NONE) {
        DTU_LOG_ERROR("Modbus exception: %s", dtu_modbus_exception_string(response.exception));
        dtu_modbus_free_response(&response);
        return DTU_ERROR;
    }

    dtu_modbus_free_response(&response);
    return DTU_OK;
}

uint16_t dtu_modbus_crc16(const uint8_t* data, size_t length)
{
    uint16_t crc = 0xFFFF;
    
    for (size_t i = 0; i < length; i++) {
        crc = (crc >> 8) ^ crc16_table[(crc ^ data[i]) & 0xFF];
    }
    
    return crc;
}

uint8_t dtu_modbus_lrc(const uint8_t* data, size_t length)
{
    uint8_t lrc = 0;
    
    for (size_t i = 0; i < length; i++) {
        lrc += data[i];
    }
    
    return (uint8_t)(0x100 - lrc);
}

const char* dtu_modbus_function_code_string(modbus_function_code_t function_code)
{
    switch (function_code) {
        case MODBUS_FC_READ_COILS: return "Read Coils";
        case MODBUS_FC_READ_DISCRETE_INPUTS: return "Read Discrete Inputs";
        case MODBUS_FC_READ_HOLDING_REGISTERS: return "Read Holding Registers";
        case MODBUS_FC_READ_INPUT_REGISTERS: return "Read Input Registers";
        case MODBUS_FC_WRITE_SINGLE_COIL: return "Write Single Coil";
        case MODBUS_FC_WRITE_SINGLE_REGISTER: return "Write Single Register";
        case MODBUS_FC_WRITE_MULTIPLE_COILS: return "Write Multiple Coils";
        case MODBUS_FC_WRITE_MULTIPLE_REGISTERS: return "Write Multiple Registers";
        default: return "Unknown Function";
    }
}

const char* dtu_modbus_exception_string(modbus_exception_t exception)
{
    switch (exception) {
        case MODBUS_EXCEPTION_NONE: return "No Exception";
        case MODBUS_EXCEPTION_ILLEGAL_FUNCTION: return "Illegal Function";
        case MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS: return "Illegal Data Address";
        case MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE: return "Illegal Data Value";
        case MODBUS_EXCEPTION_SLAVE_DEVICE_FAILURE: return "Slave Device Failure";
        case MODBUS_EXCEPTION_ACKNOWLEDGE: return "Acknowledge";
        case MODBUS_EXCEPTION_SLAVE_DEVICE_BUSY: return "Slave Device Busy";
        case MODBUS_EXCEPTION_MEMORY_PARITY_ERROR: return "Memory Parity Error";
        case MODBUS_EXCEPTION_GATEWAY_PATH_UNAVAILABLE: return "Gateway Path Unavailable";
        case MODBUS_EXCEPTION_GATEWAY_TARGET_FAILED: return "Gateway Target Failed";
        default: return "Unknown Exception";
    }
}

void dtu_modbus_free_response(modbus_response_t* response)
{
    if (response && response->data) {
        DTU_FREE(response->data);
        response->data = NULL;
        response->data_length = 0;
    }
}

/* 内部函数实现 */
static dtu_error_t configure_serial_port(int fd, const serial_config_t* config)
{
    struct termios tty;

    if (tcgetattr(fd, &tty) != 0) {
        return DTU_ERROR_NETWORK;
    }

    /* 设置波特率 */
    speed_t speed;
    switch (config->baudrate) {
        case 1200: speed = B1200; break;
        case 2400: speed = B2400; break;
        case 4800: speed = B4800; break;
        case 9600: speed = B9600; break;
        case 19200: speed = B19200; break;
        case 38400: speed = B38400; break;
        case 57600: speed = B57600; break;
        case 115200: speed = B115200; break;
        default: return DTU_ERROR_INVALID_PARAM;
    }

    cfsetispeed(&tty, speed);
    cfsetospeed(&tty, speed);

    /* 设置数据位 */
    tty.c_cflag &= ~CSIZE;
    switch (config->databits) {
        case 7: tty.c_cflag |= CS7; break;
        case 8: tty.c_cflag |= CS8; break;
        default: return DTU_ERROR_INVALID_PARAM;
    }

    /* 设置停止位 */
    if (config->stopbits == 1) {
        tty.c_cflag &= ~CSTOPB;
    } else if (config->stopbits == 2) {
        tty.c_cflag |= CSTOPB;
    } else {
        return DTU_ERROR_INVALID_PARAM;
    }

    /* 设置校验位 */
    switch (config->parity) {
        case 'N':
        case 'n':
            tty.c_cflag &= ~PARENB;
            break;
        case 'E':
        case 'e':
            tty.c_cflag |= PARENB;
            tty.c_cflag &= ~PARODD;
            break;
        case 'O':
        case 'o':
            tty.c_cflag |= PARENB;
            tty.c_cflag |= PARODD;
            break;
        default:
            return DTU_ERROR_INVALID_PARAM;
    }

    /* 其他设置 */
    tty.c_cflag |= CREAD | CLOCAL;  /* 启用接收和本地模式 */
    tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);  /* 原始模式 */
    tty.c_iflag &= ~(IXON | IXOFF | IXANY);  /* 禁用软件流控 */
    tty.c_oflag &= ~OPOST;  /* 原始输出 */

    /* 设置超时 */
    tty.c_cc[VMIN] = 0;
    tty.c_cc[VTIME] = config->timeout / 100;  /* 转换为0.1秒单位 */

    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        return DTU_ERROR_NETWORK;
    }

    return DTU_OK;
}

dtu_error_t dtu_modbus_send_request(modbus_context_t* ctx, const modbus_request_t* request, modbus_response_t* response)
{
    if (!ctx || !ctx->initialized || !request || !response) {
        return DTU_ERROR_INVALID_PARAM;
    }

    pthread_mutex_lock(&ctx->mutex);

    if (ctx->serial_fd < 0) {
        pthread_mutex_unlock(&ctx->mutex);
        return DTU_ERROR_NETWORK;
    }

    /* 构建请求帧 */
    modbus_frame_t request_frame;
    dtu_error_t ret = dtu_modbus_build_frame(ctx->mode, request, &request_frame);
    if (ret != DTU_OK) {
        pthread_mutex_unlock(&ctx->mutex);
        return ret;
    }

    /* 发送请求 */
    ret = send_frame(ctx, &request_frame);
    dtu_modbus_free_frame(&request_frame);

    if (ret != DTU_OK) {
        pthread_mutex_unlock(&ctx->mutex);
        return ret;
    }

    /* 等待响应 */
    ret = wait_for_response(ctx, ctx->response_timeout);
    if (ret != DTU_OK) {
        ctx->timeout_count++;
        pthread_mutex_unlock(&ctx->mutex);
        return ret;
    }

    /* 接收响应 */
    modbus_frame_t response_frame;
    ret = receive_frame(ctx, &response_frame);
    if (ret != DTU_OK) {
        ctx->error_count++;
        pthread_mutex_unlock(&ctx->mutex);
        return ret;
    }

    /* 解析响应 */
    ret = dtu_modbus_parse_frame(ctx->mode, &response_frame, response);
    dtu_modbus_free_frame(&response_frame);

    if (ret == DTU_OK) {
        ctx->response_count++;
    } else {
        ctx->error_count++;
    }

    ctx->request_count++;
    pthread_mutex_unlock(&ctx->mutex);

    return ret;
}

dtu_error_t dtu_modbus_build_frame(modbus_mode_t mode, const modbus_request_t* request, modbus_frame_t* frame)
{
    if (!request || !frame) {
        return DTU_ERROR_INVALID_PARAM;
    }

    memset(frame, 0, sizeof(modbus_frame_t));

    /* 计算帧长度 */
    size_t frame_len = 2 + request->data_length; /* 从站地址 + 功能码 + 数据 */

    if (request->function_code == MODBUS_FC_READ_HOLDING_REGISTERS ||
        request->function_code == MODBUS_FC_READ_INPUT_REGISTERS ||
        request->function_code == MODBUS_FC_READ_COILS ||
        request->function_code == MODBUS_FC_READ_DISCRETE_INPUTS) {
        frame_len += 4; /* 起始地址(2) + 数量(2) */
    } else if (request->function_code == MODBUS_FC_WRITE_SINGLE_REGISTER ||
               request->function_code == MODBUS_FC_WRITE_SINGLE_COIL) {
        frame_len += 4; /* 地址(2) + 值(2) */
    }

    if (mode == MODBUS_MODE_RTU) {
        frame_len += 2; /* CRC16 */
    } else {
        frame_len += 1; /* LRC */
        frame_len *= 2; /* ASCII编码 */
        frame_len += 3; /* ':' + CR + LF */
    }

    /* 分配帧缓冲区 */
    frame->frame = DTU_MALLOC(frame_len);
    if (!frame->frame) {
        return DTU_ERROR_MEMORY;
    }

    uint8_t* ptr = frame->frame;

    if (mode == MODBUS_MODE_RTU) {
        /* RTU模式 */
        *ptr++ = request->slave_id;
        *ptr++ = request->function_code;

        if (request->function_code == MODBUS_FC_READ_HOLDING_REGISTERS ||
            request->function_code == MODBUS_FC_READ_INPUT_REGISTERS ||
            request->function_code == MODBUS_FC_READ_COILS ||
            request->function_code == MODBUS_FC_READ_DISCRETE_INPUTS) {
            *ptr++ = (request->start_address >> 8) & 0xFF;
            *ptr++ = request->start_address & 0xFF;
            *ptr++ = (request->quantity >> 8) & 0xFF;
            *ptr++ = request->quantity & 0xFF;
        } else if (request->function_code == MODBUS_FC_WRITE_SINGLE_REGISTER ||
                   request->function_code == MODBUS_FC_WRITE_SINGLE_COIL) {
            *ptr++ = (request->start_address >> 8) & 0xFF;
            *ptr++ = request->start_address & 0xFF;
            if (request->data && request->data_length >= 2) {
                *ptr++ = request->data[0];
                *ptr++ = request->data[1];
            }
        }

        /* 计算并添加CRC */
        uint16_t crc = dtu_modbus_crc16(frame->frame, ptr - frame->frame);
        *ptr++ = crc & 0xFF;
        *ptr++ = (crc >> 8) & 0xFF;

        frame->crc = crc;
    } else {
        /* ASCII模式 - 简化实现 */
        /* TODO: 实现完整的ASCII模式 */
        DTU_FREE(frame->frame);
        return DTU_ERROR_NOT_SUPPORTED;
    }

    frame->frame_length = ptr - frame->frame;
    return DTU_OK;
}

void dtu_modbus_free_frame(modbus_frame_t* frame)
{
    if (frame && frame->frame) {
        DTU_FREE(frame->frame);
        frame->frame = NULL;
        frame->frame_length = 0;
    }
}

static dtu_error_t send_frame(modbus_context_t* ctx, const modbus_frame_t* frame)
{
    if (!ctx || !frame || !frame->frame || frame->frame_length == 0) {
        return DTU_ERROR_INVALID_PARAM;
    }

    ssize_t bytes_sent = write(ctx->serial_fd, frame->frame, frame->frame_length);
    if (bytes_sent != (ssize_t)frame->frame_length) {
        DTU_LOG_ERROR("Failed to send complete frame: sent %zd of %zu bytes",
                      bytes_sent, frame->frame_length);
        return DTU_ERROR_NETWORK;
    }

    /* 刷新输出缓冲区 */
    tcdrain(ctx->serial_fd);

    DTU_LOG_HEX(LOG_LEVEL_DEBUG, frame->frame, frame->frame_length, "Sent frame");
    return DTU_OK;
}

static dtu_error_t receive_frame(modbus_context_t* ctx, modbus_frame_t* frame)
{
    if (!ctx || !frame) {
        return DTU_ERROR_INVALID_PARAM;
    }

    memset(frame, 0, sizeof(modbus_frame_t));

    /* 分配接收缓冲区 */
    uint8_t buffer[256];
    size_t received = 0;

    /* 接收数据 */
    while (received < sizeof(buffer) - 1) {
        ssize_t bytes = read(ctx->serial_fd, buffer + received, 1);
        if (bytes <= 0) {
            if (received > 0) {
                break; /* 已接收到部分数据，可能是帧结束 */
            }
            return DTU_ERROR_TIMEOUT;
        }
        received += bytes;

        /* 检查帧间超时 */
        usleep(ctx->frame_timeout * 1000);
    }

    if (received == 0) {
        return DTU_ERROR_TIMEOUT;
    }

    /* 分配帧缓冲区并复制数据 */
    frame->frame = DTU_MALLOC(received);
    if (!frame->frame) {
        return DTU_ERROR_MEMORY;
    }

    memcpy(frame->frame, buffer, received);
    frame->frame_length = received;

    DTU_LOG_HEX(LOG_LEVEL_DEBUG, frame->frame, frame->frame_length, "Received frame");
    return DTU_OK;
}

static dtu_error_t wait_for_response(modbus_context_t* ctx, int timeout_ms)
{
    if (!ctx || timeout_ms <= 0) {
        return DTU_ERROR_INVALID_PARAM;
    }

    fd_set read_fds;
    struct timeval timeout;

    FD_ZERO(&read_fds);
    FD_SET(ctx->serial_fd, &read_fds);

    timeout.tv_sec = timeout_ms / 1000;
    timeout.tv_usec = (timeout_ms % 1000) * 1000;

    int result = select(ctx->serial_fd + 1, &read_fds, NULL, NULL, &timeout);
    if (result < 0) {
        return DTU_ERROR_NETWORK;
    } else if (result == 0) {
        return DTU_ERROR_TIMEOUT;
    }

    return DTU_OK;
}

dtu_error_t dtu_modbus_parse_frame(modbus_mode_t mode, const modbus_frame_t* frame, modbus_response_t* response)
{
    if (!frame || !response || !frame->frame || frame->frame_length < 3) {
        return DTU_ERROR_INVALID_PARAM;
    }

    memset(response, 0, sizeof(modbus_response_t));

    if (mode == MODBUS_MODE_RTU) {
        /* RTU模式解析 */
        const uint8_t* data = frame->frame;

        response->slave_id = data[0];
        response->function_code = (modbus_function_code_t)data[1];

        /* 检查是否是异常响应 */
        if (data[1] & 0x80) {
            response->exception = (modbus_exception_t)data[2];
            return DTU_OK;
        }

        /* 验证CRC */
        uint16_t received_crc = data[frame->frame_length - 2] | (data[frame->frame_length - 1] << 8);
        uint16_t calculated_crc = dtu_modbus_crc16(data, frame->frame_length - 2);

        if (received_crc != calculated_crc) {
            DTU_LOG_ERROR("CRC mismatch: received 0x%04X, calculated 0x%04X",
                          received_crc, calculated_crc);
            return DTU_ERROR;
        }

        /* 解析数据部分 */
        if (response->function_code == MODBUS_FC_READ_HOLDING_REGISTERS ||
            response->function_code == MODBUS_FC_READ_INPUT_REGISTERS) {
            response->byte_count = data[2];
            response->data_length = response->byte_count;

            if (response->data_length > 0) {
                response->data = DTU_MALLOC(response->data_length);
                if (response->data) {
                    memcpy(response->data, &data[3], response->data_length);
                }
            }
        }

        response->exception = MODBUS_EXCEPTION_NONE;
        return DTU_OK;
    } else {
        /* ASCII模式 - 简化实现 */
        return DTU_ERROR_NOT_SUPPORTED;
    }
}
